/*
 * DirectSocket.java
 *
 * Created on 23 ������ 2007 �., 19:11
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.jimm.protocol.net;

import java.io.*;
import java.net.*;

import org.jimm.app.JimmException;
import org.jimm.modules.Traffic;

import android.util.Log;

public class DirectSocket {
    private static final String LOG_TAG = "org.jimm.protocol.net.DirectSocket";
    private Socket socket;
    private InputStream is;
    private OutputStream os;

    public void connectTo(String host, int port) throws JimmException, IOException {

        Log.i(LOG_TAG, "host = " + host + ", port = " + port);
        socket = new Socket(host, port);
        os = new DataOutputStream(socket.getOutputStream());
        is = socket.getInputStream();
    }

    public void waitData() throws JimmException, IOException {
        while (0 == available()) {
            try {
                Thread.sleep(100);
            } catch (Exception ex) {
            }
        }
    }

    public final int read() throws JimmException {
        try {
            return is.read();
        } catch (Exception e) {
            throw new JimmException(120, 4);
        }
    }

    public int read(byte[] data) throws JimmException, IOException {
        int length = Math.min(data.length, available());
        if (0 == length) {
            return 0;
        }
        int bRead = is.read(data, 0, length);

        if (-1 == bRead) {
            throw new JimmException(120, 12);
        }
        // #sijapp cond.if modules_TRAFFIC is "true" #
        Traffic.getInstance().addInTraffic(bRead * 3 / 2);
        // #sijapp cond.end#
        return bRead;
    }

    public final int readFully(byte[] data) throws JimmException {
        if ((null == data) || (0 == data.length)) {
            return 0;
        }
        try {
            int bReadSum = 0;
            do {
                int bRead = is.read(data, bReadSum, data.length - bReadSum);
                if (-1 == bRead) {
                    throw new IOException("EOF");
                } else if (0 == bRead) {
                    waitData();
                }
                bReadSum += bRead;
            } while (bReadSum < data.length);
            // #sijapp cond.if modules_TRAFFIC is "true" #
            Traffic.getInstance().addInTraffic(bReadSum * 3 / 2);
            // #sijapp cond.end#
            return bReadSum;
        } catch (IOException e) {
            throw new JimmException(120, 1);
        }
    }

    public final void write(byte[] data) throws JimmException {
        try {
            os.write(data);
            os.flush();
        } catch (IOException e) {
            throw new JimmException(120, 2);
        }
        // #sijapp cond.if modules_TRAFFIC is "true" #
        Traffic.getInstance().addOutTraffic(data.length * 3 / 2);
        // #sijapp cond.end#
    }

    public final int available() throws IOException {
        return is.available();
    }

    // Sets the reconnect flag and closes the connection
    public final void close() throws IOException {
        socket.shutdownInput();
        socket.shutdownOutput();
        socket.close();
        is.close();
        os.close();
    }
}
